package com.lyr.test;

import com.lyr.test.custom.AopProxyOrderService;
import com.lyr.test.pojo.User;
import com.lyr.test.service.MyService;
import com.mysql.cj.jdbc.MysqlDataSource;
import org.aopalliance.aop.Advice;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.*;
import org.springframework.aop.aspectj.annotation.BeanFactoryAspectInstanceFactory;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.NameMatchMethodPointcut;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.datasource.DataSourceUtils;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.SQLException;

public class Main {
    public void say(){
        System.out.println("say");
    }
    public static void main(String[] args) throws SQLException, NoSuchMethodException, IOException {
//        ApplicationContext context = new ClassPathXmlApplicationContext("services.xml");
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        try (SqlSession session = sqlSessionFactory.openSession()) {
            User user = (User) session.selectOne("com.lyr.test.selectUser", 1);
            System.out.println(user);
        }
    }

    private static void customAdvisor(ApplicationContext context) {
        AopProxyOrderService bean = context.getBean(AopProxyOrderService.class);
        bean.crateOrder("小明");
    }


    private static void cglib() {
        System.setProperty("cglib.debugLocation",".");
        Main main = new Main();
        Enhancer enhancer = new Enhancer();

        enhancer.setSuperclass(Main.class);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println(methodProxy);
                System.out.println("before");
                Object res = method.invoke(main, objects);
                System.out.println("after");
                return res;
            }
        });

        Main o = (Main)enhancer.create();
        o.say();
    }

    private static void tx(ApplicationContext context) {
        MyService myService = (MyService) context.getBean("myService");

        System.out.println(myService.doTx());
    }

    private static void getDs(ApplicationContext context) {
        DataSource dataSource = context.getBean(DataSource.class);
        Connection conn1 = DataSourceUtils.getConnection(dataSource);
        Connection conn2 = DataSourceUtils.getConnection(dataSource);
        System.out.println(conn1 == conn2);
    }

    private static void aop(ApplicationContext context) {
        MyService myService = (MyService) context.getBean("myService");

        try {
            System.out.println(myService.performAction("normal"));
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("=======================");

        try {
            System.out.println(myService.performAction("throw"));
        } catch (Exception e) {
            System.out.println("Exception caught in main: " + e.getMessage());
        }
    }
}
